<template>
  <div class="app-container1">
    <div v-loading="listLoading" class="maincontent">
      <div class="DateSelect">
        <span style="color: gray; margin-right: 10px">请选择日期</span>
        <el-date-picker
          v-model="value"
          type="date"
          placeholder="选择日期"
          @change="handleChange"
        />
        <span>
          <el-button type="text" class="rearange" @click="handleRearange">{{
            rearrangeFlag == true ? "重排" : "排班"
          }}</el-button>
        </span>
        <span class="editSwitch">
          <el-switch
            v-model="editStatus"
            active-text="编辑模式"
            inactive-text="展示模式"
            active-color="#13ce66"
            :disabled="lock"
            @change="handleStatusChange"
          />
        </span>
      </div>
      <div ref="progressChart" class="progressChart" />
    </div>

    <!-- 编辑界面 -->

    <el-dialog width="400px" :visible.sync="editFormStatus">
      <el-form
        v-model="shiftObj"
        status-icon
        label-width="90px"
        class="rostering"
      >
        <el-form-item label="员工" class="item">
          <el-select
            v-model="shiftObj.newStaffId"
            placeholder="请选择"
            style="width: 70%; margin-bottom: 10px"
          >
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              style="margin-left: 10px"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="起始时间" class="item">
          <el-time-select
            v-model="startTime"
            placeholder="起始时间"
            :picker-options="{
              start: '08:00',
              step: '00:30',
              end: '23:59',
            }"
            style="width: 70%; margin-bottom: 10px"
          />
        </el-form-item>
        <el-form-item label="结束时间" class="item">
          <el-time-select
            v-model="endTime"
            placeholder="结束时间"
            :picker-options="{
              start: '08:30',
              step: '00:30',
              end: '23:59',
              minTime: startTime,
            }"
            style="width: 70%; margin-bottom: 10px"
          />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            class="button"
            @click="submitForm()"
          >提交</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
import {
  getshiftListByDay,
  rearrangeByDay,
  recommendEmps,
  updateSchedule
} from '@/api/shift'
import { MyformatDate } from '@/utils/MyTools'
import * as echarts from 'echarts'
let that = null
export default {
  name: 'App',
  data() {
    return {
      value: new Date(),
      staffArr: [],
      startTimeArr: [],
      endTimeArr: [],
      listLoading: true,
      rearrangeFlag: true,
      editStatus: false,
      lock: false,
      echartsData: [],
      ObjArr: [],
      shiftArr: [],
      options: [],
      list: [],
      startTime: '',
      endTime: '',
      shiftObj: {
        id: '',
        shiftId: '',
        newStaffId: '',
        newStartTime: '',
        newEndTime: ''
      },
      findIndex: '',
      editFormStatus: false
    }
  },

  watch: {
    staffArr: {
      handler(newVal, oldVal) {
        this.initChart()
      },
      deep: true
    },
    startTimeArr: {
      handler(newVal) {
        this.initChart()
      },
      deep: true
    },
    endTimeArr: {
      handler(newVal) {
        this.initChart()
      },
      deep: true
    },
    editStatus: {
      handler(newVal) {
        this.initChart()
      }
    }
  },
  mounted() {
    // 此处计时器配合 JSON.parse(JSON.stringify());可以解决mounted状态下无法访问_ob_observe数据的问题
    setTimeout(() => {
      this.initChart()
    }, 800)
    this.listLoading = false
    that = this
  },
  created() {
    this.handleShow()
    this.getshiftListByDay(this.value)
  },
  methods: {
    // 判定是否展示排班功能
    handleShow() {
      this.showStaus = this.$store.getters.roles.some((item) => item == '店长')
    },
    submitForm() {
      if (
        this.shiftObj.newStaffId == '' ||
        this.endTime == undefined ||
        this.startTime == undefined
      ) {
        this.$notify({
          title: '请填写完整信息后再提交',
          type: 'warning'
        })
      } else {
        this.$confirm('是否确定提交修改?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            this.shiftObj.newEndTime =
              this.echartsData[0].value.split(' ')[0] + ' ' + this.endTime
            this.shiftObj.newStartTime =
              this.echartsData[1].value.split(' ')[0] + ' ' + this.startTime
            this.shiftObj.id = this.list[this.findIndex].id
            this.shiftObj.shiftId = this.list[this.findIndex].shiftId
            // console.log("更新操作对象", this.shiftObj);
            updateSchedule(this.shiftObj).then((res) => {
              // console.log("调用修改接口返回的res",res)
              if (res.returnValue == 1) {
                this.$notify({
                  title: '修改成功',
                  type: 'success',
                  duration: 2000
                })
                const nameObj = this.options.filter((item) => {
                  return item.value == this.shiftObj.newStaffId
                })
                this.staffArr.splice(this.findIndex, 1, nameObj[0].label)
                this.startTimeArr.splice(
                  this.findIndex,
                  1,
                  this.shiftObj.newStartTime
                )
                this.endTimeArr.splice(
                  this.findIndex,
                  1,
                  this.shiftObj.newEndTime
                )
                this.editFormStatus = false
                const realdate = this.getEveryMonday(this.value)
                const obj = {}
                obj.storeId = this.$store.getters.storeId
                obj.m = 0
                obj.date = realdate
                this.$emit('handleRearrangeByDay', obj)
              } else {
                this.$notify({
                  title: 'Error',
                  type: 'error',
                  message: res.msg,
                  duration: 2000
                })
              }
            })
          })
          .catch(() => {
            this.editFormStatus = false
          })
      }
    },
    /* 初始化图表 */
    initChart() {
      JSON.parse(
        JSON.stringify(this.staffArr, this.endTimeArr, this.startTimeArr)
      )
      const progressChart = echarts.init(this.$refs.progressChart)
      const option = {
        // 鼠标移入提示工具
        tooltip: {
          trigger: 'axis',
          formatter(params) {
            if (params[1].data && params[0].data) {
              that.echartsData = Object.assign({}, params)
              return (
                `<div>开始时间：${params[1].data}</div>` +
                `<div>结束时间：${params[0].data}</div>`
              )
            } else {
              return ''
            }
          },
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          containLabel: true,
          show: false,
          right: 40,
          left: 40,
          bottom: 40,
          top: 20,
          backgroundColor: '#fff'
        },
        legend: {
          // 图例组件
          data: ['每日排班'],
          align: 'auto',
          top: 'bottom'
        },
        color: [
          '#5470c6',
          '#91cc75',
          '#fac858',
          '#ee6666',
          '#73c0de',
          '#3ba272',
          '#fc8452',
          '#9a60b4',
          '#ea7ccc',
          '#D32F2F',
          '#FFCDD2',
          '#F44336',
          '#FF4081',
          '#FBC02D',
          '#FFF9C4',
          '#FFEB3B',
          '#BDBDBD',
          '#0288D1',
          '#B3E5FC',
          '#009688',
          '#689F38',
          '#DCEDC8',
          '#8BC34A',
          '#7C4DFF',
          '#7B1FA2',
          '#E1BEE7',
          '#9C27B0',
          '#0097A7',
          '#B2EBF2',
          '#00BCD4',
          '#FF9800',
          '#F57C00',
          '#FFE0B2',
          '#5D4037',
          '#D7CCC8',
          '#795548',
          '#455A64',
          '#CFD8DC',
          '#607D8B',
          '#9E9E9E',
          '#FFA000',
          '#FFECB3',
          '#FFC107',
          '#303F9F',
          '#C5CAE9',
          '#3F51B5'
        ],
        xAxis: {
          type: 'time',
          position: 'top', // x 轴位置
          axisTick: {
            // 隐藏刻度
            show: false
          },
          axisLine: {
            // 隐藏轴线
            show: false
          },
          splitLine: {
            // 显示网格线
            show: true
          }
          // 自定义调色盘的颜色
        },
        yAxis: {
          inverse: true, // y 轴数据翻转，该操作是为了保证项目一放在最上面，项目七在最下面
          axisTick: {
            // 隐藏刻度
            show: false
          },
          axisLine: {
            // 隐藏轴线
            show: false
          },
          data: this.staffArr
        },
        series: [
          {
            name: '每日排班',
            type: 'bar',
            stack: 'duration',
            colorBy: 'data',
            itemStyle: {
              borderColor: '#fff',
              borderWidth: 1
            },
            zlevel: -1,
            // 结束时间
            // data: [
            //   "2023-01-31",
            //   "2023-02-25",
            //   "2023-03-25",
            //   "2023-04-01",
            //   "2023-04-10",
            //   "2023-05-25",
            //   "2023-07-25",
            // ],
            data: this.endTimeArr
          },
          {
            name: '每日排班',
            type: 'bar',
            stack: 'duration', // 堆叠标识符，同个类目轴上系列配置相同的 stack 值可以堆叠放置
            itemStyle: {
              color: '#fff'
            },
            zlevel: -1, // zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面
            z: 9, // z值小的图形会被z值大的图形覆盖，z相比zlevel优先级更低，而且不会创建新的 Canvas
            // 开始时间
            // data: [
            //   "2023-01-01",
            //   "2023-01-31",
            //   "2023-02-25",
            //   "2023-03-25",
            //   "2023-04-01",
            //   "2023-04-10",
            //   "2023-05-25",
            // ],
            data: this.startTimeArr
          }
        ]
      }
      progressChart.setOption(option)
      // 浏览器窗口大小变化，图表大小自适应
      window.addEventListener('resize', () => {
        progressChart.resize()
      })
      if (this.editStatus) {
        progressChart.off('dblclick')
        progressChart.on('dblclick', function(params) {
          // console.log("在这执行的", that.echartsData);
          // 获取推荐人员
          const data = {}
          that.shiftObj.newStaffId = ''
          data.storeId = that.$store.getters.storeId
          data.date = that.echartsData[0].data.split(' ')[0]
          data.shiftId = that.shiftArr[params.dataIndex].shiftId
          data.staffId = that.ObjArr[params.dataIndex].staffId
          // console.log("获取推荐员工的数据",data);
          recommendEmps(data).then((res) => {
            const Arr = []
            if (res.returnValue == 1) {
              that.editFormStatus = true
              for (var item of res.data) {
                const obj = {}
                obj.label = item.name
                obj.value = item.id
                Arr.push(obj)
              }
              const originObj = {}
              // console.log("本地员工id",that.ObjArr[params.dataIndex].staffId)
              // console.log("本地员工id",that.ObjArr[params.dataIndex].name)
              originObj.label = that.ObjArr[params.dataIndex].name
              originObj.value = that.ObjArr[params.dataIndex].staffId
              Arr.unshift(originObj)
              that.options = Arr
              that.shiftObj.newStaffId = that.ObjArr[params.dataIndex].staffId
              that.findIndex = params.dataIndex
              that.startTime = that.echartsData[1].data.split(' ')[1]
              that.endTime = that.echartsData[0].data.split(' ')[1]
            } else {
              that.$notify({
                title: 'Error',
                type: 'error',
                duration: 2000,
                message: res.msg
              })
            }
          })
        })
      }
    },
    initData(list) {
      this.staffArr = []
      this.startTimeArr = []
      this.endTimeArr = []
      if (list.length > 0) {
        for (let i = 0; i < list.length; i++) {
          if (list[i].staff == null) {
            const data =
              list[i].staff == null ? '开放班次' : list[i].staff.name
            this.staffArr[i] = data
            this.startTimeArr[i] = list[i].shift.startTime
            this.endTimeArr[i] = list[i].shift.endTime
          } else {
            this.staffArr[i] = list[i].staff.name
            this.startTimeArr[i] = list[i].shift.startTime
            this.endTimeArr[i] = list[i].shift.endTime
          }
        }
      }
    },
    initShiftArr(List) {
      this.shiftArr = []
      if (List.length > 0) {
        for (const item of List) {
          const obj = {}
          obj.shiftId = item.shiftId
          this.shiftArr.push(obj)
        }
      }
    },
    getEveryMonday(realdate) {
      function getNextDate(date, day) {
        var dd = new Date(date)
        dd.setDate(dd.getDate() + day)
        var y = dd.getFullYear()
        var m =
          dd.getMonth() + 1 < 10
            ? '0' + (dd.getMonth() + 1)
            : dd.getMonth() + 1
        var d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate()
        return y + '-' + m + '-' + d
      }
      const differentDays =
        realdate.getDay() - 1 == -1 ? 6 : realdate.getDay() - 1
      // console.log("相差的",differentDays);
      const targetDate = getNextDate(realdate, -differentDays)
      // console.log("周一日期",targetDate);
      return targetDate
    },
    // 初始化人员id表
    initObj(List) {
      this.ObjArr = []
      if (List.length > 0) {
        for (const item of List) {
          const obj = {}
          obj.name = item.staff == undefined ? '' : item.staff.name
          obj.staffId = item.staff == undefined ? '' : item.staff.id
          this.ObjArr.push(obj)
        }
      }
    },
    // 获取排班列表
    getshiftListByDay(val) {
      this.value = val
      const returnDate = MyformatDate(val)
      const storeId = this.$store.getters.storeId
      const obj = {}
      obj.storeId = storeId
      obj.date = returnDate
      // console.log(obj)
      getshiftListByDay(obj).then((res) => {
        if (res.returnValue == 1) {
          this.list = res.data
          this.initObj(this.list)
          this.initShiftArr(this.list)
          this.initData(this.list)
          this.initChart()
          this.rearrangeFlag = true
        } else {
          this.AutoRearrange()
          this.rearrangeFlag = true
        }
      })
    },
    handleChange(val) {
      if (val != null) {
        const returnDate = MyformatDate(val)
        const storeId = this.$store.getters.storeId
        const obj = {}
        obj.storeId = storeId
        obj.date = returnDate
        getshiftListByDay(obj).then((res) => {
          // console.log("按日排班的数据", res);
          if (res.returnValue == 1) {
            // console.log("数据",res.data)
            this.list = res.data
            this.initObj(this.list)
            this.initShiftArr(this.list)
            this.initData(this.list)
            this.initChart()
            this.rearrangeFlag = true
          } else {
            this.AutoRearrange()
            this.rearrangeFlag = true
          }
        })
        this.initChart()
      }
    },
    handleRearange() {
      const promptInformation =
        this.rearrangeFlag == true
          ? '此操作将会重新为当日进行一次排班，是否确认进行此操作？'
          : '此操作将会进行一次排班，是否确认进行此操作？'
      this.$confirm(promptInformation, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          const obj = {}
          obj.storeId = this.$store.getters.storeId
          obj.date = MyformatDate(this.value)
          this.listLoading = true
          // console.log("手动排班对象(按日)", obj);
          rearrangeByDay(obj).then((res) => {
            // console.log(res);
            if (res.returnValue == 1) {
              const list = res.data
              this.rearrangeFlag = true
              this.initData(list)
              this.initShiftArr(list)
              this.initObj(list)
              this.listLoading = false
              this.$notify({
                title: 'Success',
                type: 'success',
                message: res.msg
              })
              this.$emit('handleRearrangeByDay', obj)
            } else {
              this.$notify({
                title: 'Error',
                type: 'error',
                message: res.msg
              })
              this.listLoading = false
            }
          })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消操作'
          })
        })
    },
    handleStatusChange() {
      const msg = this.editStatus == false ? '展示' : '编辑'
      this.$notify({
        title: `${msg}模式`,
        message: `你已成功切换至${msg}模式`,
        type: 'success',
        duration: 2000
      })
      if (msg == '编辑') {
        this.$alert('你可以通过双击任一排班表进行排班', '', {
          confirmButtonText: '确定'
        })
      }
      this.$emit('handleStatusChange', this.editStatus)
      this.lock = true
      setTimeout(() => {
        this.lock = false
      }, 500)
    },
    AutoRearrange() {
      const obj = {}
      obj.storeId = this.$store.getters.storeId
      obj.date = MyformatDate(this.value)
      this.listLoading = true
      // console.log("手动排班对象(按日)", obj);
      rearrangeByDay(obj).then((res) => {
        // console.log(res);
        if (res.returnValue == 1) {
          const list = res.data
          this.rearrangeFlag = true
          this.initData(list)
          this.initShiftArr(list)
          this.initObj(list)
          this.listLoading = false
          this.$emit('handleRearrangeByDay', obj)
        } else {
          const list = []
          this.initData(list)
          this.initShiftArr(list)
          this.initObj(list)
          this.$notify({
            title: 'Error',
            type: 'error',
            message: '未查找到排班信息',
            duration: 2000
          })
          this.listLoading = false
        }
      })
    },
    getDayList(val) {
      // console.log("getDatList",val);
      const storeId = this.$store.getters.storeId
      const obj = {}
      obj.storeId = storeId
      obj.date = val
      getshiftListByDay(obj).then((res) => {
        if (res.returnValue == 1) {
          this.value = val
          this.list = res.data
          this.initObj(this.list)
          this.initShiftArr(this.list)
          this.initData(this.list)
          this.initChart()
          this.rearrangeFlag = true
        } else {
          this.AutoRearrange()
          this.rearrangeFlag = true
        }
      })
    }
  }
}
</script>

<style scoped>
.app-container1 {
  width: 100%;
  height: 100%;
  /* overflow: hidden scroll; */
}
* {
  padding: 0px;
  margin: 0px;
}
.rosteringForm {
  height: 800px;
  width: 800px;
  background: transparent;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  padding: 0px;
  border-radius: 10px;
  transition: none;
  transition: none;
}
.rostering {
  padding: 10px;
  width: 400px;
  position: relative;
  left: 50%;
  transform: translate(-45%);
  /* border: 1px solid black; */
}
.DateSelect {
  width: 50%;
  height: 10%;
  padding: 1%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* border: 1px solid black; */
}
.maincontent {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 750px;
  /* border: 1px solid black; */
}
.editSwitch {
  margin-left: 5%;
}
.progressChart {
  width: 900px;
  height: 100%;
  padding: 10px;
  margin-bottom: 20px;
  border: 1px solid #aaa;
  /* transform: translateY(-10px); */
}
.rearange {
  margin-left: 20px;
  padding: 10px;
  width: 60px;
  border: 1px solid rgb(230, 228, 228);
  color: black;
  font-weight: 300;
}
.rosterForm {
  width: 60%;
  height: 100%;
  position: absolute;
  left: calc(50%);
  top: calc(50%);
  transform: translateX(-50%) translateY(-50%);
}
.item {
  margin: 10px;
}
.button {
  padding: 10px 15px 10px 15px;
  transform: translateX(20%);
}
</style>
